package com.cloud.pole.user.service.account.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.cloud.pole.api.param.PicklistApi;
import com.cloud.pole.common.constant.CommonConstants;
import com.cloud.pole.common.exception.BaseException;
import com.cloud.pole.common.msg.ApiRestResponse;
import com.cloud.pole.common.util.jwt.IJWTInfo;
import com.cloud.pole.common.util.jwt.JwtTokenUtil;
import com.cloud.pole.feign.IParamPickListService;
import com.cloud.pole.user.biz.BaseUserBiz;
import com.cloud.pole.user.biz.account.UserAccountBankBiz;
import com.cloud.pole.user.biz.account.UserAccountBiz;
import com.cloud.pole.user.biz.account.UserAccountTypeBiz;
import com.cloud.pole.user.biz.account.UserWithdrawBiz;
import com.cloud.pole.user.model.entity.BaseUser;
import com.cloud.pole.user.model.entity.account.UserAccount;
import com.cloud.pole.user.model.entity.account.UserAccountBank;
import com.cloud.pole.user.model.entity.account.UserAccountType;
import com.cloud.pole.user.model.entity.account.UserWithdraw;
import com.cloud.pole.user.model.vo.account.UserWithdrawParamsVo;
import com.cloud.pole.user.service.account.UserAccountService;
import com.cloud.pole.user.service.account.UserWithdrawService;

import lombok.extern.slf4j.Slf4j;

/*
*2019年3月25日
*cloud-user
*author:frank-chen
*/
@Service
@Slf4j
public class UserWithdrawServiceImpl implements UserWithdrawService {
    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);

	@Autowired
    private UserAccountBiz userAccountBiz;
	@Autowired
    private UserAccountTypeBiz userAccountTypeBiz;
	@Autowired
    private BaseUserBiz userBiz;
	@Autowired
    private UserAccountService userAccountService;
	@Autowired
    private UserWithdrawBiz userWithdrawBiz;
	@Autowired
    private UserAccountBankBiz userAccountBankBiz;
	@Autowired
    private IParamPickListService paramPickListService;
	
	@Override
	public Boolean addUserWithdraw(String token, Long accountId, String bankTypeId, String bankName, String userRealName,
			String userCardNo, Integer amount, String payPwd) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jwtInfo = JwtTokenUtil.getInfoFromToken(token);
		Long userId = Long.parseLong(jwtInfo.getId());
		UserAccount userAccount = userAccountBiz.selectByPrimaryKey(accountId);
		if(userAccount == null || userAccount.getAccountStatus() != UserAccount.USER_ACCOUNT_STATUS_OK || 
		   userAccount.getUserId().longValue() != userId.longValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "账号错误");
		}		
		Integer typeId = userAccount.getTypeId();
		//判断typeId是否正确
		UserAccountType userAccountType = userAccountTypeBiz.selectByTypeId(typeId);
		if(userAccountType == null || userAccountType.getTypeStatus() != 1) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "typeId错误");
		}
		//是否可以提现
		if(userAccountType.getWithdrawFlag() != UserAccountType.WITHDRAW_FLAG_YES)
		{
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "账号不能提现");
		}
		//判断amount是否正确
		if(amount.intValue() <= 0) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "金额错误");
		}	
		//最小提现金额(单位0.01)
		if(amount.intValue() < userAccountType.getMinWithdraw().intValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "低于最小提现金额" +  (userAccountType.getMinWithdraw().intValue() / 100));
		}	
		//最大提现金额(单位0.01)
		if(amount.intValue() > userAccountType.getMaxWithdraw().intValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "超过最大提现金额" + (userAccountType.getMaxWithdraw().intValue() / 100));
		}	
		//提现整数倍基数(单位0.01)
		if(amount.intValue() % userAccountType.getMultipleNumWithdraw() != 0) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "每次提现金额必须是" + (userAccountType.getMultipleNumWithdraw()  / 100) + "的倍数");
		}
		//判断用户是否正确
		BaseUser baseUser = userBiz.getUserByUserName(jwtInfo.getUniqueName());
		if(baseUser == null || baseUser.getUserStatus() != 1 || baseUser.getUserId().longValue() != userId.longValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "用戶错误");
		}
		//验证支付密码是否正确
		if(!encoder.matches(payPwd, baseUser.getPayPwd())){                     
			throw new BaseException(CommonConstants.USER_PAYPWD_ERROR, CommonConstants.USER_PAYPWD_ERROR_MESSAGE);
		}	
		if(userAccount.getAccountBalance().compareTo(BigDecimal.valueOf(amount)) < 0 ) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "余额不足");
		}	   
	    ApiRestResponse<String> apiRestResponse = paramPickListService.getPickListText(PicklistApi.PICKLIST_CODE_BANKTYPE, bankTypeId);
	    if(apiRestResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
			throw new BaseException(apiRestResponse.getStatus(), apiRestResponse.getMessage());
	    }
	    if(StringUtils.isEmpty(apiRestResponse.getData())) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "bankTypeId错误");
	    }
	    String bankTypeName = apiRestResponse.getData();
	    Integer taxAccount = 0;
	    Integer realAccount = amount - taxAccount;
	    //保存提现记录
	    UserWithdraw msg = new UserWithdraw();
	    msg.setBankCardNo(userCardNo);
	    msg.setBankUserName(userRealName);
	    msg.setBankName(bankName);
	    msg.setBankTypeId(bankTypeId);
	    msg.setBankTypeName(bankTypeName);
	    msg.setBillFlag(0);
	    msg.setMemo("");
	    msg.setRealAccount(realAccount);
	    msg.setTaxAccount(taxAccount);
	    msg.setUserId(userId);
	    msg.setUserName(jwtInfo.getUniqueName());
	    msg.setWithdrawStatus(UserWithdraw.WITHDRAW_STATUS_DEFAULT);
	    msg.setWithdrawAccount(amount);
	    msg.setWithdrawTime(new Date());
	    userWithdrawBiz.insertUseGeneratedKeys(msg);
	    
	    int status = userAccountService.handleBalance(typeId, userId, jwtInfo.getUniqueName(), String.valueOf(msg.getWithdrawId()), Integer.valueOf(UserWithdraw.OBJECT_TYPE_ID_USERWITHDRAW), new BigDecimal(amount), null, "", "", "");
		if(status == 0) {
			userWithdrawBiz.deleteByPrimaryKey(msg.getWithdrawId());
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "提现错误");
		}
	    //保存银行卡信息
		
		UserAccountBank userAccountBank = userAccountBankBiz.selectByUserId(userId);
		if(userAccountBank == null) {
			userAccountBank = new UserAccountBank();
			userAccountBank.setAccountStatus(UserAccountBank.ACCOUNT_STATUS_OK);
			userAccountBank.setBankCardNo(userCardNo);
			userAccountBank.setBankName(bankName);
			userAccountBank.setBankTypeId(bankTypeId);
			userAccountBank.setBankTypeName(bankTypeName);
			userAccountBank.setCreateTime(new Date());
			userAccountBank.setUserId(userId);
			userAccountBank.setUserName(jwtInfo.getUniqueName());
			userAccountBankBiz.insertSelective(userAccountBank);
		}
		else {
			userAccountBank.setAccountStatus(UserAccountBank.ACCOUNT_STATUS_OK);
			userAccountBank.setBankCardNo(userCardNo);
			userAccountBank.setBankName(bankName);
			userAccountBank.setBankTypeId(bankTypeId);
			userAccountBank.setBankTypeName(bankTypeName);
			userAccountBankBiz.updateByPrimaryKey(userAccountBank);
		}
		return true;
	}

	@Override
	public UserWithdrawParamsVo getUserWithdrawParams(String token, Long accountId) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jwtInfo = JwtTokenUtil.getInfoFromToken(token);
		Long userId = Long.parseLong(jwtInfo.getId());
		UserWithdrawParamsVo withdrawParamsVo= new UserWithdrawParamsVo();
		UserAccount userAccount = userAccountBiz.selectByPrimaryKey(accountId);
		if(userAccount == null || userAccount.getAccountStatus() != UserAccount.USER_ACCOUNT_STATUS_OK || 
		   userAccount.getUserId().longValue() != userId.longValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "账号错误");
		}		
		//判断typeId是否正确
		UserAccountType userAccountType = userAccountTypeBiz.selectByTypeId(userAccount.getTypeId());
		if(userAccountType == null || userAccountType.getTypeStatus() != 1) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "typeId错误");
		}
		//是否可以提现
		if(userAccountType.getWithdrawFlag() != UserAccountType.WITHDRAW_FLAG_YES)
		{
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "账号不能提现");
		}
	    ApiRestResponse<List<PicklistApi>> apiRestResponse = paramPickListService.getPickList(PicklistApi.PICKLIST_CODE_BANKTYPE);
	    if(apiRestResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
			throw new BaseException(apiRestResponse.getStatus(), apiRestResponse.getMessage());
	    }
		UserAccountBank userAccountBank = userAccountBankBiz.selectByUserId(userId);

		withdrawParamsVo.setAccountBalance(userAccount.getAccountBalance());
		withdrawParamsVo.setPickList(apiRestResponse.getData());
		withdrawParamsVo.setUserAccountBank(userAccountBank);
		withdrawParamsVo.setUserAccountType(userAccountType);
		return withdrawParamsVo;
	}
}
